package DataStructure;

import OBJ.TextureLoader;
import org.joml.Vector3f;
import org.lwjgl.opengl.GL46;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static org.lwjgl.opengl.GL11C.*;

public class Model {
    private List<Vector3f> vertices;                        // 顶点
    private List<TextureCoordinate> textureCoordinates;     // 纹理坐标
    private List<Normal> normals;                           // 法线
    private List<Face> faces;                               // 面
    public List<Material> materials = new ArrayList<>();    // 材质

    //构造函数
    public Model() {
        this.vertices           = new ArrayList<>();
        this.textureCoordinates = new ArrayList<>();
        this.normals            = new ArrayList<>();
        this.faces              = new ArrayList<>();
    }
    // get  and  set 方法
    public List<Vector3f> getVertices()                    { return vertices; }
    public List<TextureCoordinate> getTextureCoordinates() { return textureCoordinates; }
    public List<Normal> getNormals()                       { return normals; }
    public List<Face> getFaces()                           { return faces; }
    public void set(List<Vector3f> vertices,
                    List<TextureCoordinate> textureCoordinates,
                    List<Normal> normals,
                    List<Face> faces) {
        this.vertices           = vertices;
        this.textureCoordinates = textureCoordinates;
        this.normals            = normals;
        this.faces              = faces;
    }

    // 内部材质类
    public static class Material {
        public String name = "Unnamed";                                 // 默认名称
        public Vector3f diffuseColor = new Vector3f(1,1,1);    // 默认白色
        public int textureID = -1;                                      // -1表示未使用贴图
        public int startIndex;                                          // 该材质在EBO中的起始索引
        public int faceCount;                                           // 该材质包含的面数
        public List<Face> faces = new ArrayList<>();                    // 该材质包含的面
        public String path;                                             // 贴图路径
        public BufferedImage textureImage;                              // 纹理图像
        // 加载纹理时应用参数
        public void loadTexture() {
            textureID = TextureLoader.loadTexture(path);
            // 加载图像到textureImage
            try {
                textureImage = ImageIO.read(new File(path));
            } catch (IOException e) {
                e.printStackTrace();
                textureImage = null;
            }
            textureID = TextureLoader.loadTexture(path);                                                    // 加载纹理
            GL46.glBindTexture(GL46.GL_TEXTURE_2D, textureID);                                              // 绑定2D纹理到当前纹理单元，后续操作将作用于这个纹理
            GL46.glTexParameteri(GL46.GL_TEXTURE_2D, GL46.GL_TEXTURE_WRAP_S, GL_REPEAT);                    // 设置纹理坐标轴S（水平方向）的环绕模式为重复（超出[0,1]范围时平铺重复）
            GL46.glTexParameteri(GL46.GL_TEXTURE_2D, GL46.GL_TEXTURE_WRAP_T, GL_REPEAT);                    // 设置纹理坐标轴T（垂直方向）的环绕模式为重复
            GL46.glTexParameteri(GL46.GL_TEXTURE_2D, GL46.GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);  // 设置缩小时（纹理缩小到比原生尺寸小）的过滤方式：使用线性Mipmap线性插值（三线性过滤）
            GL46.glTexParameteri(GL46.GL_TEXTURE_2D, GL46.GL_TEXTURE_MAG_FILTER, GL_LINEAR);                // 设置放大时（纹理放大到比原生尺寸大）的过滤方式：使用线性插值（双线性过滤）
            GL46.glGenerateMipmap(GL46.GL_TEXTURE_2D);                                                      // 为当前绑定的纹理生成多级渐远纹理（Mipmaps），用于不同距离的细节层级渲染
        }
    }
    @Override
    public String toString() {
        return "Model{" +
                "vertices=" + vertices +
                ", textureCoordinates=" + textureCoordinates +
                ", normals=" + normals +
                ", faces=" + faces +
                '}';
    }
}